﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MetroFramework.Forms;
using System.Reflection;
using Newtonsoft.Json;
using System.Configuration;
using Microsoft.Toolkit.Uwp.Notifications;
using System.IO;
using System.Threading;
using DataTurnClient.Properties;
using Newtonsoft.Json.Linq;
using DataTurnClient.Model;
using DataTurnClient.Server;
using DataTurnClient.Enum;
using Splat;
using DataTurnClient.Interface;

namespace DataTurnClient
{
    public partial class MainTurn : MetroForm 
    {
        public MainTurn()
        {
            InitializeComponent();
            Locator.CurrentMutable.RegisterLazySingleton(() => new DBHelperService());
            Locator.CurrentMutable.RegisterLazySingleton(() => new TimeService());
            Locator.CurrentMutable.RegisterLazySingleton(() => new LogService());
        }
        //////////////////////////////////////////////
        ///写在之前
        ///时间字符串规则
        ///0:00     用:分割，前面的代表时间类型，后面代表具体的value
        ///层级，列表0代表时，列表1代表分，列表2代表秒，列表3代表如果是之间类型，所要执行的时间
        ///时间类型代码，0-未启用，1-固定类型，2-循环类型，3-之间类型
        ///特殊说明。3-之间类型
        ///例：0:00,3:87,0:00,2:20
        ///此例为，在时间是早上8点到晚上7点之间，每20分钟循环执行
        ///例：1:01

        /// <summary>
        /// 启动时需要启动的一些东西
        /// </summary>
        private void Form1_Load(object sender, EventArgs e)
        {
            SelectSet();
            ///12小时刷新一次job视图
            timer.Interval = setList.FirstOrDefault().timer;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(SelectJob);
            timer.AutoReset = true;
            timer.Enabled = true;
            SelectJob(null, null);
            this.FormClosing += Form1_FormClosing;
            this.SizeChanged += Form1_SizeChanged;
            this.metroGrid1.DataSource = jobList;
            this.metroGrid2.DataSource = logList;
            System.Timers.Timer t1 = new System.Timers.Timer(1000);
            t1.Elapsed += new System.Timers.ElapsedEventHandler(AllRunTime);
            t1.AutoReset = true;
            t1.Enabled = true;
        }

        /// <summary>
        /// 任务列表
        /// </summary>
        public BindingList<Job> jobList { get; set; } = new BindingList<Job>();
        /// <summary>
        /// 日志列表
        /// </summary>
        public BindingList<Log> logList { get; set; } = new BindingList<Log>();

        /// <summary>
        /// 设置列表
        /// </summary>
        public BindingList<GetSetting> setList { get; set; } = new BindingList<GetSetting>();

        /// <summary>
        /// 同步任务定时器
        /// </summary>
        public System.Timers.Timer timer { get; set; } = new System.Timers.Timer();

        /// <summary>
        /// 当前行数据
        /// </summary>
        public Job CurrentRows {
            get {
                int a = metroGrid1.CurrentRow.Index;
                _CurrentRows = jobList[a];
                return _CurrentRows;
            }
            set {
                _CurrentRows = value;
            }
        }
        private Job _CurrentRows;
        /// <summary>
        /// 获取当前时间
        /// </summary>
        public List<string> NewTime {
            get
            {
                _NewTime = DateTime.Now.ToString("HH-mm-ss").Split('-').ToList();
                return _NewTime;
            }
            set {
                _NewTime = value;
            }
        }
        private List<string> _NewTime;
        /*------系统方法------*/
        /// <summary>
        /// 传输一个文本，显示到界面
        /// </summary>
        /// <param name="conect"></param>
        public void AddLog(string content)
        {
            this.Invoke(new Action(() => {
                logList.Add(new Log
                {
                    HappenTime = DateTime.Now,
                    HappenDtal = content
                });
                if (logList.Count > setList.FirstOrDefault().log)
                {
                    logList.RemoveAt(0);
                }
            }));
            if (setList.FirstOrDefault().dingset.on == 1)
            {
                ///钉钉发送
                Tool.DingSend.MsgSend(
                    setList.FirstOrDefault().dingset.url,
                    setList.FirstOrDefault().dingset.safecode,
                    content);
            }
        }
        /// <summary>
        /// 从数据库加载任务到视图
        /// </summary>
        private void SelectJob(object sender, EventArgs e)
        {
            try
            {
                var service = Locator.Current.GetService<DBHelperService>();
                using (var db = service.SqlSugarClient(setList.FirstOrDefault().database.connect, setList.FirstOrDefault().database.db))
                {
                    var DbJobList = db.Queryable<Job>().ToList();
                    foreach (var jobItem in DbJobList)
                    {
                        var isJob = jobList.Where(x => x.JobCode == jobItem.JobCode).FirstOrDefault();
                        if (isJob == null)
                        {
                            jobItem.JobRunStatus = Job.JobRunType.Wating;
                            jobList.Add(jobItem);
                        }
                        else
                        {
                            isJob.JobRunStatus = Job.JobRunType.Wating;
                            isJob.JobName = jobItem.JobName;
                            isJob.JobStatus = jobItem.JobStatus;
                            isJob.JobRunTime = jobItem.JobRunTime;
                            isJob.JobWeek = jobItem.JobWeek;
                            isJob.JobRoute = jobItem.JobRoute;
                            isJob.JobDetail = jobItem.JobDetail;
                            isJob.JobMode = jobItem.JobMode;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                AddLog(ex.Message);
            }
        }//Job显示方法

        /// <summary>
        /// 从json加载到内存
        /// </summary>
        private void SelectSet()
        {
            string FilePath = @".\Setting.json";
            if (setList.FirstOrDefault() == null)
            {
                setList.Add(JsonToList<GetSetting>(FilePath));
            }
            else
            {
                //写数组0是因为设置配置只能有一个实体，那么方便后续扩展，索性先不改了、
                setList[0].session = JsonToList<GetSetting>(FilePath).session;
                if(setList[0].timer != JsonToList<GetSetting>(FilePath).timer)
                {
                    timer.Interval =JsonToList<GetSetting>(FilePath).timer;
                }
                setList[0].timer = JsonToList<GetSetting>(FilePath).timer;
                setList[0].log = JsonToList<GetSetting>(FilePath).log;
                setList[0].log = JsonToList<GetSetting>(FilePath).log;
                setList[0].database.connect = JsonToList<GetSetting>(FilePath).database.connect;
                setList[0].database.db = JsonToList<GetSetting>(FilePath).database.db;
                setList[0].dingset.on = JsonToList<GetSetting>(FilePath).dingset.on;
                setList[0].dingset.url = JsonToList<GetSetting>(FilePath).dingset.url;
                setList[0].dingset.safecode = JsonToList<GetSetting>(FilePath).dingset.safecode;
            }
        }

        /// <summary>
        /// 更改视图运行状态，开启线程执行任务
        /// </summary>
        /// <param name="jobs">任务代码</param>
        private void RunJob(string jobs)
        {
            var job = jobList.Where(x => x.JobCode == jobs).ToList().FirstOrDefault();
            job.JobRunStatus = Job.JobRunType.Run;
            Func<List<Job>,List<GetSetting>,string,MsgTrun> myFunc = new Func<List<Job>, List<GetSetting>, string, MsgTrun>(HttpService.Execute);
            AsyncCallback myCallBack = getResult;
            myFunc.BeginInvoke(jobList.ToList(), setList.ToList(), jobs, myCallBack, myFunc);
        }

        public void getResult(IAsyncResult ar)
        {
            Func<List<Job>, List<GetSetting>, string, MsgTrun> func = (Func<List<Job>, List<GetSetting>, string, MsgTrun>)ar.AsyncState;
            MsgTrun ss = func.EndInvoke(ar);
            AddLog(JsonConvert.SerializeObject(ss));
        }

        /// <summary>
        /// 右键更改任务的运行状态
        /// </summary>
        public void ChangeJobStatus()
        {
            int isRun = CurrentRows.JobStatus == 0 ? 1 : 0;
            var server = Locator.Current.GetService<DBHelperService>();
            using (var db = server.SqlSugarClient(setList.FirstOrDefault().database.connect, setList.FirstOrDefault().database.db))
            {
                var results = db.Updateable<Job>()
                                            .SetColumns(it => it.JobStatus == isRun)
                                            .Where(it => it.JobCode == CurrentRows.JobCode).ExecuteCommand();
            }
            var logserver = Locator.Current.GetService<LogService>();
            logserver.WriterText("update ", DateTime.Now.ToString("HH-mm-ss") + "      " + JsonConvert.SerializeObject(CurrentRows));
        }
        /*------系统方法------*/

        /*------任务------*/
        /// <summary>
        /// 运行所有状态为1的任务
        /// </summary>
        private void AllRun()
        {
            var logserver = Locator.Current.GetService<LogService>();
            logserver.WriterText("head ", DateTime.Now.ToString("HH-mm-ss") + "      所有任务运行");
            var job = jobList.Where(x => x.JobStatus == 1 && x.JobRunStatus != Job.JobRunType.Run).ToList();
            if (job.Count > 0)
            {
                foreach (var jobs in job)
                {
                    RunJob(jobs.JobCode);
                }
            }
            else
            {
                AddLog("任务列表为空");
            }
        }
        /// <summary>
        /// 定时器专用执行方法
        /// </summary>
        /// <param name="sender"></param>
        private void AllRunTime(object sender, EventArgs e)
        {
            if (metroCheckBox5.Checked)
            {
                var job = jobList.Where(x => x.JobStatus == 1).ToList();
                if (job.Count > 0)
                {
                    var service = Locator.Current.GetService<TimeService>();
                    foreach (var jobs in job)
                    {
                        if (service.IsTime(jobs.Times,NewTime) && service.IsWeek(jobs.JobRunTime))
                        {
                            var logserver = Locator.Current.GetService<LogService>();
                            RunJob(jobs.JobCode);
                            logserver.WriterText("Time ", DateTime.Now.ToString("HH-mm-ss") + "      " + JsonConvert.SerializeObject(jobs));
                        }
                    }
                }
                else
                {
                    AddLog("任务列表为空");
                }
            }
        }
        /*------任务------*/

        /*------系统事件------*/
        private void Form1_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            if (MessageBox.Show("是否确认退出程序？", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                // 关闭所有的线程
                this.Dispose();
                this.Close();
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void Form1_SizeChanged(object sender, System.EventArgs e)
        {
            //判断是否选择的是最小化按钮
            if (WindowState == FormWindowState.Minimized)
            {
                //隐藏任务栏区图标
                this.ShowInTaskbar = false;
                //图标显示在托盘区
                notifyIcon1.Visible = true;
                this.Visible = false;
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, System.EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                //还原窗体显示    
                WindowState = FormWindowState.Normal;
                //激活窗体并给予它焦点
                this.Activate();
                //任务栏区显示图标
                this.ShowInTaskbar = true;
                //托盘区图标隐藏
                notifyIcon1.Visible = false;
                this.Visible = true;
            }
        }
        /*------系统事件------*/

        /*------右键方法------*/
        private void 刷新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SelectJob(null,null);
        }

        private void 全部执行一次ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AllRun();
        }

        private void 关闭ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("是否确认退出程序？", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                // 关闭所有的线程
                this.Dispose();
                this.Close();
            }
        }

        private void 显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                //还原窗体显示    
                WindowState = FormWindowState.Normal;
                //激活窗体并给予它焦点
                this.Activate();
                //任务栏区显示图标
                this.ShowInTaskbar = true;
                //托盘区图标隐藏
                notifyIcon1.Visible = false;
                this.Visible = true;
            }
        }

        private void 更改状态ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeJobStatus();
            SelectJob(null, null);
        }//job右键的更改状态事件

        private void 执行一次ToolStripMenuItem_Click(object sender, EventArgs e)//job右键的执行事件
        {
            if (CurrentRows.JobRunStatus == Job.JobRunType.Run)
            {
                MessageBox.Show("任务正在运行，请等待任务完成");
            }
            else if (CurrentRows.JobStatus == 1)
            {
                var logserver = Locator.Current.GetService<LogService>();
                RunJob(CurrentRows.JobCode);
                logserver.WriterText("head ", DateTime.Now.ToString("HH-mm-ss") + "      " + JsonConvert.SerializeObject(CurrentRows));
            }
            else
            {
                MessageBox.Show("任务状态为不启用(0)，如需启用请右键更改状态");
            }
        }

        private void metroLink4_Click(object sender, EventArgs e)
        {
            //psjytz();
        }

        /*------右键方法------*/

        private void metroLink1_Click(object sender, EventArgs e)
        {
            /*
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "请选择配置文件";
            ofd.Filter = "Json文件(*.json)|*.json";
            ofd.Multiselect = false;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string FilePath = ofd.FileName;
                //FilePath所选文件路径D:\DataTurn\DataTurnClient\DataJob.json
                MessageBox.Show(JsonToList<GetSetting>(FilePath).ToString());
            }*/
            SelectSet();
        }//数据库选择事件


        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        private static T JsonToList<T>(string filePath)
        {
            try
            {
                string jsonStr = File.ReadAllText(filePath);
                //反序列化
                var list = JsonConvert.DeserializeObject<T>(jsonStr);
                return list;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message+"读取配置文件错误，请检查当前目录是否有Setting.json文件或不为一个标准的json格式内容");
                return default(T);
            }
        }

            private void metroLink2_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            form2.Show();
        }//定时器设置事件

        private void 清理日志ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            logList.Clear();
        }
    }
}
